import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import * as dat from 'dat.gui';
import { CSS3DRenderer, CSS3DObject } from 'three/examples/jsm/renderers/CSS3DRenderer.js';
let myThree = {
    threeElement: null,
    scene: null,
    camera: null,
    renderer: null,
    css3DRenderer: null,
    controls: null,
    resizeTimer: null,
    rotateSwitch: true,
    InitThree(id) {
        // 初始DOM
        this.threeElement = id ? document.querySelector(id) : document.body;
        this.threeElement.style.position = 'relative';
        let _resizeObserver = new ResizeObserver(entries => {
            //回调
            this.BoxResize();
        });
        //监听对应的dom
        _resizeObserver.observe(this.threeElement);
        // 初始化场景
        this.scene = new THREE.Scene();
        // 初始化渲染器
        this.renderer = new THREE.WebGLRenderer({
            antialias: true,
        });
        this.css3DRenderer = new CSS3DRenderer();
        // 初始化相机
        this.camera = this.CreateCamera();
        const cube = this.CreateCube();
        let faceArr = ['./images/px.jpg', './images/nx.jpg', './images/py.jpg', './images/ny.jpg', './images/pz.jpg', './images/nz.jpg'];
        let textureLoader = new THREE.TextureLoader();
        // textureLoader.setPath('./images/');
        let materialArr = faceArr.map(url => {
            const face = textureLoader.load(require(`${url}`));
            face.colorSpace = THREE.SRGBColorSpace;
            return new THREE.MeshBasicMaterial({
                map: face,
                side: THREE.DoubleSide,
            });
        });
        cube.material = materialArr;
        cube.scale.set(1, 1, -1);
        this.camera.position.x = 0.1;
        this.camera.position.z = 0;
        this.camera.position.y = 0;

        // 设置渲染器比例
        this.renderer.setSize(this.threeElement.offsetWidth, this.threeElement.offsetHeight);
        this.css3DRenderer.setSize(this.threeElement.offsetWidth, this.threeElement.offsetHeight);
        this.css3DRenderer.domElement.style.position = 'absolute';
        this.css3DRenderer.domElement.style.top = '0';
        this.css3DRenderer.domElement.style.left = '0';
        this.css3DRenderer.domElement.style.pointerEvents = 'none';
        document.querySelector(id).append(this.css3DRenderer.domElement);
        document.querySelector(id).append(this.renderer.domElement);
        // 开启控制器
        this.CreateControl();
        // 开启渲染
        this.UpdateThree();
        // 辅助线
        const axesHelper = new THREE.AxesHelper(5);
        this.scene.add(axesHelper);
        // 开启GUI
        // this.CreateGui();
        // 开启点击事件
        this.threeElement.addEventListener('click', e => this.GetObject(e));
    },
    CreateCube() {
        const geometry = new THREE.BoxGeometry(1, 1, 1);

        // let materialArr = colorArr.map(color => new THREE.MeshBasicMaterial({ color: color, side: THREE.DoubleSide }));
        const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
        const cube = new THREE.Mesh(geometry, material);
        cube.name = 'box';
        this.scene.add(cube);

        return cube;
    },
    CreateCamera(
        option = [
            75, //角度
            1, // window.innerWidth / window.innerHeight,
            0.1, //近点
            1000, //远点
        ]
    ) {
        return new THREE.PerspectiveCamera(...option);
    },
    UpdateThree() {
        requestAnimationFrame(() => {
            this.UpdateThree();
            if (true) {
                this.controls.autoRotate = this.rotateSwitch;
                this.controls.update();
                this.renderer.render(this.scene, this.camera);
                this.css3DRenderer.render(this.scene, this.camera);
            }
        });
    },
    BoxResize() {
        if (this.resizeTimer) {
            clearTimeout(this.resizeTimer);
            this.resizeTimer = null;
        }
        this.resizeTimer = setTimeout(() => {
            this.renderer.setSize(this.threeElement.offsetWidth, this.threeElement.offsetHeight);
            this.css3DRenderer.setSize(this.threeElement.offsetWidth, this.threeElement.offsetHeight);
            this.camera.aspect = this.threeElement.offsetWidth / this.threeElement.offsetHeight;
            this.camera.updateProjectionMatrix();
        }, 500);
    },
    CreateGui() {
        const gui = new dat.GUI();
        gui.add(document, 'title');
    },
    CreateControl() {
        this.controls = new OrbitControls(this.camera, this.renderer.domElement);
        this.controls.enableDamping = true;
        this.controls.autoRotate = true;
        this.controls.update();
    },
    GetObject(event) {
        const raycaster = new THREE.Raycaster();
        const pointer = new THREE.Vector2();
        pointer.x = (event.clientX / window.innerWidth) * 2 - 1;
        pointer.y = -(event.clientY / window.innerHeight) * 2 + 1;
        raycaster.setFromCamera(pointer, this.camera);
        const intersects = raycaster.intersectObjects(this.scene.children);
        console.log(intersects);
    },
};
let gui = {
    target: null,
    init() {
        this.target = new dat.GUI();
    },
};
export default myThree;
